using System;
using System.Collections;
using AopAlliance.Aop;
using log4net;
using Spring.Aop.Framework;
using Spring.Core;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;

namespace Sedna.Core.Spring
{
	/// <summary>
	/// this postprocessor is registered automatically within the Spring context
	/// and creates auto-proxy for those objects that implement specified tag interface.
	/// 
	/// this auto proxy post processor is used for creating DAO and domain services (see Infra.xml file).
	/// </summary>
	public class AutoProxyObjectPostProcessor : IObjectPostProcessor, IObjectFactoryAware, IOrdered
	{

        private ILog log = LogManager.GetLogger(typeof(AutoProxyObjectPostProcessor));
	    
		private Type tagInterface;
		private IObjectFactory objectFactory;
        private IList interceptorNames;
	    private int order;

	    public IObjectFactory ObjectFactory
		{
			set { this.objectFactory = value; }
		}

        public int Order
        {
            get { return order; }
            set { order = value; }
        }
	    
		public Type TagInterface
		{
			set { tagInterface = value; }
		}

	    public IList InterceptorNames
	    {
	        set { interceptorNames = value;}
	    }
	    
		public object PostProcessBeforeInitialization(object instance, string name)
		{
			return instance;
		}

		public object PostProcessAfterInitialization(object instance, string name)
		{
			if(!tagInterface.IsInstanceOfType(instance))
			{
				return instance;
			}
			ProxyFactory proxyFactory = new ProxyFactory(instance);
		    if (interceptorNames != null)
		    {
		        foreach (String interceptorName in interceptorNames)
		        {
                    proxyFactory.AddAdvice((IAdvice)objectFactory.GetObject(interceptorName));

                    #region Log Debug

                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Add interceptor '{0}' for '{1}'({2})", interceptorName, name, instance.GetType());
                    }
		            
                    #endregion
                }
		    }			
            return proxyFactory.GetProxy();		    
		}

	}
}
